#include <cxxomfort/base.hpp>
#if (CXXOMFORT_CXX_STD<2011)
    #error "C++>=11"
#endif
#include "../entero/entero.hpp"
#include "../entero/io.hpp"
#include <cxxomfort/ostream.hpp>
#include <cxxomfort/library/type_name.hpp>
#include <cxxomfort/algorithm.hpp>
#include <cxxomfort/library/algorithm.hpp>
#include <iostream>

const size_t Z= 6;
const size_t NZ = 4;
typedef lpp::entero::EnteroU<NZ> NT;
namespace algorithm2= cxxomfort::library::algorithm;
using cxxomfort::type_name;

int main () {
    using namespace std;
    cout<< CHAR_BIT<< " "<< __CHAR_BIT__<< endl;
    srand(time(0));
    cout<< "uintH: "<< type_name<lpp::entero::impl::uintH>()<< endl;
    array<NT,Z> nrs;
    array<int,Z> nlogs;
    generate(begin(nrs), end(nrs), lpp::entero::random_raw<NZ>);
    for (unsigned idx= 0; idx < nrs.size(); ++idx) {
        nrs[idx]>>= (rand()%(4+NZ))*idx;
    }
    sort(begin(nrs), end(nrs));
    for (unsigned idx= 0; idx < nrs.size(); ++idx) {
        nlogs[idx]= nrs[idx].leftmost1();
    }
    cout<< "Numbers:\n";
    unsigned idx= 0;
    cout<< nrs[0]<< endl;
    CXXO_FOREACH(NT const& n, nrs) {
        string inp;
        cout<< idx<< " \t"<< n<< " \t"<< hex<< n<< dec<< " \t"<< hex<< nlogs[idx]<< dec<< " \n";
        ++idx;
        //cin>> inp;
    }
    cout<< endl;
/*
    array<uintmax_t,Z> urs;
    for (size_t i=0; i < Z; ++i) {
        urs[i]= explicit_cast<uintmax_t>(nrs[i]);
    }
    idx= 0;
    CXXO_FOREACH(uintmax_t const n, urs) {
        cout<< idx++<< " \t"<< hex<< n<< dec<< "\n";
    }
*/
    
    NT add1 = nrs[2] + nrs[4];
    cout<< "add1 n2+n4 :\t"<< hex<< add1<< dec<< endl;
    //assert(add1 - nrs[2] == nrs[4]);

    return 0;

    NT sub1 = nrs[1] - nrs[0];
    cout<< "sub1 n1-n0 :\t"<< sub1<< endl;
    //(assert(sub1 + nrs[0] == nrs[1]);

    // subst should underflow
    NT sub2 = nrs[3] - nrs[5];
    cout<< "sub2 n3-n5 :\t"<< sub2<< endl;
    
    NT mul1 = nrs[3] * nrs[0];
    cout<< "mul1 n3*n0 :\t"<< mul1<< endl;

    
    NT div1 = nrs[5] / nrs[0];
    cout<< "div1 n5/n0 :\t"<< div1<< endl;
    NT mod1 = nrs[5] % nrs[0];
    cout<< "mod1 n5%n0 :\t"<< mod1<< endl;

}
